import copy
import importlib
import os
from typing import Callable, Union

import lib.pubvars
from Plugins.tools.PluginList import Pluginlist
from lib.log import logger

all_events = {}


def save_events(event_key: str, module_name: str, event_object: Union[str, Callable]):
    if isinstance(event_object, str):
        try:
            event_object = getattr(importlib.import_module(f"Plugins.{module_name}"), event_key)
        except ImportError as e:
            logger.error(f"无法导入模块: {e}")
        except AttributeError:
            pass
    event = all_events.get(event_key, [])
    event.append(event_object)
    all_events[event_key] = event


def process_thread_class(thread_class, target_func, page):

    if not page:
        thread_class.run(target=target_func)
    else:
        thread_class.run(target=target_func, page=page)


def initialize_plugin(name, page):
    """
    初始化插件并执行相应操作。

    Args:
        name (str): 插件的名称。
        page (Page): 插件的页面对象。
    """

    # 遍历所有可能的插件文件来使装饰器生效
    for root, _, files in os.walk("Plugins"):
        if root != "Plugins":
            break
        for file in files:
            if file.endswith(".py"):
                importlib.import_module('.' + file.split(".")[0], package="Plugins")

    skipped_plugins_counter = 0
    all_known_dependencies = {}  # 初始化用于保存依赖项的字典
    pluginlist = copy.deepcopy(Pluginlist)

    # 针对单个插件信息的处理
    for plugin in pluginlist:
        if plugin.on == name:
            if len(pluginlist) == skipped_plugins_counter:
                break
            elif plugin.dependencies == "" or plugin.dependencies == []:  # 对于有依赖项的插件先延后处理
                dep = all_known_dependencies.get(plugin.name, set())  # 先获取对应的键
                for i in plugin.dependencies:
                    dep.append(i)
                all_known_dependencies[plugin.name] = list(set(dep))
                logger.info(f"插件{plugin.name}制定了依赖项字段,将被延后加载")
                skipped_plugins_counter += 1
                continue
            else:  # 先加载没依赖项的插件
                load_info = f"加载插件:{plugin.name}"
                logger.info(f"{load_info:=^50}")
                logger.info(f"插件描述:{plugin.description}")
                logger.info(f"插件版本:{plugin.version}")
                logger.info(f"插件作者:{plugin.author}")
                logger.info(f"入口点文件:{plugin.file}")

                if isinstance(plugin.on_load, Callable):
                    target_func = plugin.on_load
                else:
                    m = importlib.import_module('Plugins.' + os.path.basename(plugin.file).split('.')[0])
                    target_func = getattr(m, plugin.on_load, None)
                target_thread_class = plugin.thread_class

                # 处理插件需要获取的程序变量和函数
                for event_key in ["on_load", "on_unload", "on_enable", "on_disable"]:
                    save_events(event_key, os.path.basename(plugin.file).split('.')[0], getattr(plugin, event_key))
                need_page = plugin.need_page
                if hasattr(target_thread_class, "run"):
                    target_thread_class = target_thread_class
                else:
                    target_thread_class = None

                # 处理完成,准备调用
                if target_thread_class is None:
                    logger.debug("没有使用thread类,将直接调用函数")
                    if not need_page:
                        target_func()
                    else:
                        target_func(page)
                else:
                    logger.debug("检测到使用了thread类")
                    process_thread_class(target_thread_class, target_func, page)

                logger.info(f"{load_info:=^50}")
                pluginlist.remove(plugin)  # 删除加载完毕的插件

    lib.pubvars.PubVars.plugin_list = Pluginlist
